/*
* Copyright (c) 2025 Shenzhen Kaihong Digital Industry Development Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const { XButton } = require("../../engine/control/XButton");
const { X2DBeta, X3DFast } = require("../../engine/graphics/X2DInterface");
const { XMat4 } = require("../../engine/graphics/XMat4");
const { Scr } = require("../../engine/XDefine");
const { XTools } = require("../../engine/XTools");
const { LogManager } = require("../ros1/LogManager");
const { CreateCustomPart } = require("./CreateCustomPart");
const { RobotManager } = require("./RobotManager");
const { SaveRobotConfig } = require("./SaveRobotConfig");

class SelectRobotPart {
    static getInstance() {
        if (!SelectRobotPart.instance) {
            SelectRobotPart.instance = new SelectRobotPart();
        }
        return SelectRobotPart.instance;
    }
    constructor() {
        this.on = false;
        this.operate = false;
        this.tabPoint = 0;
        this.btn_tabs = [
            new XButton({
                name: "自定义部件",
                onClick: () => { this.tabPoint = 0; }
            }),
            new XButton({
                name: "预设部件",
                onClick: () => { this.tabPoint = 1; }
            }),
            new XButton({
                name: "部件商店",
                onClick: () => { this.tabPoint = 2; }
            })
        ];
        this.partPoint = -1;
        this.partBtns = [];
        this.customParts = [//todo remove default
            // { "token": "xMdStWrrg6pZbPe5", "name": "test1", "type": "box", "mass": 1, "xyz": { "x": 0, "y": 0, "z": 0 }, "rpy": { "x": 0, "y": 0, "z": 0 }, "box": { "x": 1, "y": 1, "z": 1 }, "bounds": { "min": [-0.5, -0.5, -0.5], "max": [0.5, 0.5, 0.5] }, "material": "color", "color": { "r": 1, "g": 1, "b": 1, "a": 1 } },
            // { "token": "fq1fF952rhf0l7SM", "name": "test2", "type": "cylinder", "mass": 1, "xyz": { "x": 0, "y": 0, "z": 0 }, "rpy": { "x": 0, "y": 0, "z": 0 }, "cylinder": { "radius": 0.5, "height": 1 }, "bounds": { "min": [-0.5, -0.5, -0.5], "max": [0.5, 0.5, 0.5] }, "material": "color", "color": { "r": 1, "g": 1, "b": 1, "a": 1 } },
            // { "token": "LnMYDrQMd6LUoBVQ", "name": "test3", "type": "box", "mass": 1, "xyz": { "x": 0, "y": 0, "z": 0 }, "rpy": { "x": 0, "y": 0, "z": 0 }, "box": { "x": 1, "y": 1, "z": 1 }, "bounds": { "min": [-0.5, -0.5, -0.5], "max": [0.5, 0.5, 0.5] }, "material": "color", "color": { "r": 1, "g": 1, "b": 1, "a": 1 } },
        ];
        this.tmat = new XMat4();
        this.btn_newCustomPart = new XButton({
            name: "新建自定义部件",
            onClicked: () => {
                this.on = false;
                this.operate = "create_custom_part";
            }
        });

        this.btn_editCustomPart = new XButton({
            name: "修改所选部件",
            onClicked: () => {
                this.on = false;
                this.selectedPart = JSON.parse(JSON.stringify(this.customParts[this.partPoint]));
                this.operate = "edit_custom_part";
            }
        });
        this.btn_deleteCustomPart = new XButton({
            name: "删除所选部件",
            onClicked: () => {
                const { RobotManager } = require("./RobotManager");
                let rbs = RobotManager.getInstance().robots;
                for (let robot of rbs) {
                    for (let part of robot.parts) {
                        if(part.token == this.customParts[this.partPoint].token){
                            LogManager.E(`所选部件在机器人${robot.name}中被使用，不能删除`);
                            this.on = false;
                            return;
                        }
                    }
                }
                this.customParts.splice(this.partPoint, 1);
                this.partPoint = -1;
                this.operate = false;
            }
        });
        this.btn_addToRobot = new XButton({
            name: "添加到机器人",
            onClicked: () => {
                this.on = false;
                this.operate = "add_to_robot";
                this.selectedPart = JSON.parse(JSON.stringify(this.customParts[this.partPoint]));
                console.log("----------------", JSON.stringify(this.customParts[this.partPoint]));
            }
        });

        this.btn_cancel = new XButton({
            name: "取消",
            onClicked: () => {
                this.on = false;
            }
        });
    }
    open() {
        this.on = true;
        this.operate = false;
    }
    onDraw() {
        let x = 100;
        let y = 100;
        let w = Scr.logicw - 420 - x * 2;
        let h = Scr.logich - y * 2;
        this.rect = [x, y, w, h];
        X2DBeta.fillRect(x, y, w, h, 0xff101010);


        for (let i = 0; i < this.btn_tabs.length; i++) {
            let btn = this.btn_tabs[i];
            let ww = w / 3;
            let xx = x + ww * i;
            let hh = 20;
            btn.move(xx, y, ww, 20);
            if (i == this.tabPoint) {
                X2DBeta.fillRect(xx + 1, y, ww - 2, hh, 0xff800000);
            } else {
                X2DBeta.fillRect(xx + 1, y, ww - 2, hh, 0xff400000);
            }

            X2DBeta.drawText(btn.name_, 14, xx + ww / 2, y + hh / 2, 1, 1, 0, -2, -2, 0xffffffff);
        }

        if (this.tabPoint == 0) {
            for (let i = this.partBtns.length; i < this.customParts.length; i++) {
                let btn = new XButton({
                    onClicked: () => {
                        this.partPoint = btn.pp;
                    }
                });
                this.partBtns.push(btn);
            }
            let dx = x;
            let dy = y + 20;

            for (let i = 0; i < this.customParts.length; i++) {
                X3DFast.swapMode3D();
                this.renderCustomPart(this.customParts[i].token, dx + 50, dy + 40);
                X2DBeta.swapMode2D();
                let bx = dx + 5;
                let by = dy + 5;
                let bw = 100 - 10;
                let bh = 100 - 10;
                if (this.partPoint == i) {
                    X2DBeta.drawRect(bx, by, bw, bh, 0xff00ff00, 3);
                }
                else if (XTools.mouseIn(bx, by, bw, bh)) {
                    X2DBeta.drawRect(bx, by, bw, bh, 0xff00ff00, 1);
                } else {
                    X2DBeta.drawRect(bx, by, bw, bh, 0xffffffff, 1);
                }
                X2DBeta.drawText(this.customParts[i].name, 14, dx + 50, dy + 85, 1, 1, 0, -2, -2, 0xffffffff);
                this.partBtns[i].pp = i;
                this.partBtns[i].move(bx, by, bw, bh);
                dx += 100;
                if (dx >= w) {
                    dx = x;
                    dy += 100;
                }
            }

            let opBtns = [this.btn_newCustomPart];
            if (this.partPoint >= 0 && this.partPoint < this.customParts.length) {
                opBtns.push(this.btn_editCustomPart, this.btn_deleteCustomPart, this.btn_addToRobot);
            }
            for (let i = 0; i < opBtns.length; i++) {
                opBtns[i].move(x + 10 + 110 * i, y + h - 30, 100, 20).onDraw();
            }
        }
        this.btn_cancel.move(x + w - 110, y + h - 30, 100, 20).onDraw();
    }
    searchCustomPart(token) {
        for (let i = 0; i < this.customParts.length; i++) {
            if (this.customParts[i].token == token) {
                return this.customParts[i];
            }
        }
        return null;
    }
    renderCustomPart(token, dx, dy) {
        for (let part of this.customParts) {
            if (part.token == token) {
                let w = Math.max(Math.abs(part.bounds.min[0]), Math.abs(part.bounds.max[0])) * 2;
                let h = Math.max(Math.abs(part.bounds.min[2]), Math.abs(part.bounds.max[2])) * 2;
                let scale = Math.min(50 / w, 50 / h);
                this.tmat.Unit();
                this.tmat.Scale(scale, scale, scale);
                this.tmat.Rotate(0, 0, XTools.TIME_MS / 20);
                this.tmat.Rotate(15, 0, 0);
                // this.tmat.Move(-Scr.logicw / 2, -Scr.logich / 2, 0);
                this.tmat.Move(dx - Scr.logicw / 2, 0, Scr.logich / 2 - dy);
                CreateCustomPart.renderPart(part, this.tmat);
                break;
            }
        }
    }
    renderCustomPart3(token, mat, withBounds = false, pickPoint = 0) {
        for (let part of this.customParts) {
            if (part.token == token) {
                CreateCustomPart.renderPart(part, mat, withBounds, pickPoint);
                break;
            }
        }
    }
    pick(options) {
        for (let part of this.customParts) {
            if (part.token == options.token) {
                if (CreateCustomPart.pick(part, options)) {
                    return true;
                }
                return false;
            }
        }
        return false;
    }
    onTouch(msg, x, y) {
        for (let i = 0; i < this.btn_tabs.length; i++) {
            if (this.btn_tabs[i].onTouch(msg, x, y)) {
                if (this.btn_tabs[i].IsClicked()) {
                    this.tabPoint = i;
                }
                return true;
            }
        }
        if (this.tabPoint == 0) {
            if (this.btn_newCustomPart.onTouch(msg, x, y)) return true;
            if (this.partPoint >= 0 && this.partPoint < this.customParts.length) {
                if (this.btn_editCustomPart.onTouch(msg, x, y)) return true;
                if (this.btn_deleteCustomPart.onTouch(msg, x, y)) return true;
                if (this.btn_addToRobot.onTouch(msg, x, y)) return true;
            }
            for (let i = 0; i < this.customParts.length; i++) {
                if (this.partBtns[i].onTouch(msg, x, y)) return true;
            }
        }
        if (this.btn_cancel.onTouch(msg, x, y)) return true;
        if (XTools.InRect(x, y, ...this.rect)) {
            return true;
        }
        return false;
    }
    createPart(part) {//创建新的自定义部件
        if (part != null) {
            let isModify = false;
            for (let i = 0; i < this.customParts.length; i++) {
                if (this.customParts[i].token == part.token) {
                    isModify = true;
                    this.customParts[i] = part;
                    SaveRobotConfig.getInstance().saveConfig();
                    break;
                }
            }
            if (!isModify) {
                this.customParts.push(part);
                SaveRobotConfig.getInstance().saveConfig();
            }
        }
        const { EditRobot } = require("./EditRobot");
        EditRobot.getInstance().open();
        this.open();
    }
}

module.exports = {
    SelectRobotPart
}